package com.xdcplus.web.service.bd.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageInfo;
import com.xdcplus.core.utils.BeanUtils;
import com.xdcplus.exceptions.XdcWebException;
import com.xdcplus.mom.constants.NumberConstant;
import com.xdcplus.mom.enums.ResponseEnum;
import com.xdcplus.mp.service.impl.BaseServiceImpl;
import com.xdcplus.mp.utils.PageableUtils;
import com.xdcplus.mp.utils.PropertyUtils;
import com.xdcplus.pager.vo.PageVO;
import com.xdcplus.web.common.pojo.dto.bd.BdMaterialFilterDTO;
import com.xdcplus.web.common.pojo.dto.bd.BdSupplierDTO;
import com.xdcplus.web.common.pojo.dto.bd.BdSupplierFilterDTO;
import com.xdcplus.web.common.pojo.entity.bd.BdSupplier;
import com.xdcplus.web.common.pojo.query.bd.BdSupplierQuery;
import com.xdcplus.web.common.pojo.vo.bd.BdMaterialVO;
import com.xdcplus.web.common.pojo.vo.bd.BdSupplierVO;
import com.xdcplus.web.mapper.bd.BdSupplierMapper;
import com.xdcplus.web.service.bd.BdMaterialService;
import com.xdcplus.web.service.bd.BdSupplierService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.util.Arrays;
import java.util.List;

/**
 * 供应商表(BdSupplier)表服务实现类
 *
 * @author Fish.Fei
 * @since 2023-01-31 17:36:34
 */
@Slf4j
@Service("bdSupplierService")
public class BdSupplierServiceImpl extends BaseServiceImpl<BdSupplierMapper, BdSupplier, BdSupplier, BdSupplierVO> implements BdSupplierService {

    @Autowired
    protected BdSupplierMapper bdSupplierMapper;

    @Autowired
    protected BdMaterialService bdMaterialService;

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public Boolean saveBdSupplier(BdSupplierDTO bdSupplierDTO) {
        //检查供应商Code是否存在
        checkCodeIsExists(bdSupplierDTO.getSupplierCode(),null);
        checkNameIsExists(bdSupplierDTO.getSupplierFullname(),null);
        BdSupplier bdSupplier = new BdSupplier();
        BeanUtil.copyProperties(bdSupplierDTO, bdSupplier);
        bdSupplier.setCreatedTime(new Timestamp(DateUtil.current()));
        
        return this.save(bdSupplier);
    }

    /**
     * 检查供应商Code是否存在
     * @param supplierCode 供应商Code
     * @param supplierId  供应商id
     */
    private void checkSupplierCodeIsExists(String supplierCode,Long supplierId) {
        BdSupplier bdSupplierIsExists=bdSupplierMapper.queryBdSupplierBySupplierCode(supplierCode);
        if(bdSupplierIsExists!=null && bdSupplierIsExists.getId()!=supplierId){
            throw new XdcWebException(ResponseEnum.ERROR,ResponseEnum.CODE_ALREADY_EXISTS.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public Boolean updateBdSupplier(BdSupplierDTO bdSupplierDTO) {

        BdSupplier bdSupplier = this.getById(bdSupplierDTO.getId());
        if (ObjectUtil.isNull(bdSupplier)) {
            log.error("updateBdSupplier() The BdSupplier does not exist or has been deleted");
            throw new XdcWebException(ResponseEnum.ERROR);
        }
        //检查供应商Code是否存在
        checkCodeIsExists(bdSupplierDTO.getSupplierCode(),bdSupplierDTO.getId());
        checkNameIsExists(bdSupplierDTO.getSupplierFullname(),bdSupplierDTO.getId());

        BeanUtil.copyProperties(bdSupplierDTO, bdSupplier);
        bdSupplier.setUpdatedUser(bdSupplierDTO.getUpdatedUser());
        bdSupplier.setUpdatedTime(new Timestamp(DateUtil.current()));

        return this.updateById(bdSupplier);
    }

    @Override
    public Boolean saveOrUpdateBatch(List<BdSupplier> bdSupplierList) {

        bdSupplierList.forEach(bdSupplier -> {
            BdSupplier bdSupplierParam = new BdSupplier();
            bdSupplierParam.setId(bdSupplier.getId());
            if (ObjectUtil.isNotNull(bdSupplier.getId())) {
                bdSupplier.setId(bdSupplier.getId());
                bdSupplier.setUpdatedTime(new Timestamp(DateUtil.current()));
                LambdaUpdateWrapper<BdSupplier> lambdaUpdate = Wrappers.lambdaUpdate();
                lambdaUpdate.eq(BdSupplier::getId, bdSupplier.getId());
                update(bdSupplier, lambdaUpdate);
            } else {
                bdSupplier.setCreatedTime(new Timestamp(DateUtil.current()));
                save(bdSupplier);
            }
        });
        return true;
    }

    @Override
    public Boolean saveOrUpdateBatchByDTOList(List<BdSupplierDTO> bdSupplierDTOList) {

        List<BdSupplier> bdSupplierList = BeanUtils.copyProperties(bdSupplierDTOList, BdSupplier.class);
        return saveOrUpdateBatch(bdSupplierList);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public Boolean deleteBdSupplierLogical(Long id) {

        Assert.notNull(id, ResponseEnum.THE_ID_CANNOT_BE_EMPTY.getMessage());

        BdSupplier bdSupplier = this.getById(id);

        if (ObjectUtil.isNull(bdSupplier)) {
            log.error("deleteBdSupplier() The BdSupplier does not exist or has been deleted");
            throw new XdcWebException(ResponseEnum.ERROR);
        }

        BdMaterialFilterDTO bdMaterialFilterDTO = new BdMaterialFilterDTO();
        bdMaterialFilterDTO.setSupplierIdFk(id);
        List<BdMaterialVO> bdMaterialVOS = bdMaterialService.queryBdMaterialVOList(bdMaterialFilterDTO);
        Assert.isTrue(CollectionUtil.isEmpty(bdMaterialVOS),ResponseEnum.DATA_QUOTE.getMessage());

        return this.removeById(id);
    }
    
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public Boolean deleteBdSupplierByIds(String ids) {
        Assert.notNull(ids, ResponseEnum.THE_ID_CANNOT_BE_EMPTY.getMessage());
		List<String> idList = Arrays.asList(ids.split(","));
		if(CollectionUtil.isEmpty(idList)){
           throw new XdcWebException(ResponseEnum.ERROR);
       }
		idList.forEach(id->{
			BdSupplier bdSupplier = this.getById(id);
			if (ObjectUtil.isNull(bdSupplier)) {
				log.error("deleteBdSupplier() The BdSupplier does not exist or has been deleted");
				throw new XdcWebException(ResponseEnum.ERROR);
			}
		});
		
        return this.removeByIds(idList);
    }

    private List<BdSupplier> queryBdSupplierList(BdSupplierFilterDTO bdSupplierFilterDTO) {
        BdSupplierQuery bdSupplierQuery = BeanUtil.copyProperties(bdSupplierFilterDTO, BdSupplierQuery.class);

        return bdSupplierMapper.queryBdSupplier(bdSupplierQuery);
    }

    @Override
    public List<BdSupplierVO> queryBdSupplierVOList(BdSupplierFilterDTO bdSupplierFilterDTO) {
        return this.objectConversion(queryBdSupplierList(bdSupplierFilterDTO));
    }

    @Override
    public PageVO<BdSupplierVO> queryBdSupplier(BdSupplierFilterDTO bdSupplierFilterDTO) {
        PageVO<BdSupplierVO> pageVO = new PageVO<>();

        if (bdSupplierFilterDTO.getCurrentPage() > NumberConstant.ZERO) {
            PageableUtils.basicPage(bdSupplierFilterDTO.getCurrentPage(), bdSupplierFilterDTO.getPageSize(),
                    bdSupplierFilterDTO.getOrderType(), bdSupplierFilterDTO.getOrderField());
        }

        List<BdSupplier> bdSupplierList = queryBdSupplierList(bdSupplierFilterDTO);

        PageInfo<BdSupplier> pageInfo = new PageInfo<>(bdSupplierList);
        PropertyUtils.copyProperties(pageInfo, pageVO, this.objectConversion(bdSupplierList));

        return pageVO;
    }

    @Override
    public BdSupplierVO queryBdSupplierById(Long id) {

        Assert.notNull(id, ResponseEnum.THE_ID_CANNOT_BE_EMPTY.getMessage());

        return this.objectConversion(this.getById(id));
    }

    @Override
    public String getSupplierNameById(Long id) {
        if(id==null){
            return null;
        }
        BdSupplier bdSupplier=this.getById(id);
        if(bdSupplier!=null){
            return bdSupplier.getSupplierName();
        }
        return null;
    }

    @Override
    public BdSupplierVO queryBdSupplierVoBySupplierCode(String supplierCode) {
        return this.objectConversion(bdSupplierMapper.queryBdSupplierBySupplierCode(supplierCode));
    }

    /**
     * 检验Code是否存在
     */
    private void checkCodeIsExists(String code,Long id){
        BdSupplier bdSupplier = bdSupplierMapper.selectOne(new QueryWrapper<BdSupplier>().eq("SUPPLIER_CODE", code));

        if(bdSupplier==null || (id!=null && bdSupplier.getId().equals(id))){
            return;
        }
        throw new XdcWebException(ResponseEnum.SUPPLIER_CODE_ALREADY_EXISTS);
    }

    /**
     * 检验Name是否存在
     */
    private void checkNameIsExists(String name,Long id){
        BdSupplier bdSupplier = bdSupplierMapper.selectOne(new QueryWrapper<BdSupplier>().eq("SUPPLIER_NAME", name));

        if(bdSupplier==null || (id!=null && bdSupplier.getId().equals(id))){
            return;
        }
        throw new XdcWebException(ResponseEnum.SUPPLIER_NAME_ALREADY_EXISTS);
    }

}
